import { defineStore } from "pinia";
import { computed, Ref, ref, watch } from "vue";
import { basename } from "@tauri-apps/api/path";
import {
  cvsStatus,
  cvsStatusMulti,
  CVSStatusText,
  NotCVSFileError,
  CVSFile,
} from "../utils/cvs";
import { replaceContent } from "../utils/file";
import { Store } from "../utils/store";

export interface FileItem {
  name: string;
  path: string;
  status: string;
  rawStatus: string;
  workingVersion: string;
  repositoryVersion: string;
  baseVersionTag?: string; // 基线版本tag
  selected: boolean; // 添加选中状态字段
  statusSnapshot?: CVSFile;
}

export interface Tag {
  name: string;
  updateTime: number;
}

export interface TagGroup {
  reqNumber: string;
  tags: Tag[]; // 按照更新时间倒序排列
}

export const useTagStore2 = defineStore("tag", () => {
  const store = new Store("tag");

  // tag列表
  const tags = ref<Tag[]>([]);
  // 分组后的tag列表
  const tagGroups = computed<TagGroup[]>(() => {
    const reqGroups: Record<string, Tag[]> = {};
    tags.value.forEach((item) => {
      const reqNumber = extractReqNumber(item.name);
      if (!reqGroups[reqNumber]) {
        reqGroups[reqNumber] = [];
      }
      reqGroups[reqNumber].push(item);
    });
    const result = Object.values(reqGroups).map((group) => ({
      reqNumber: extractReqNumber(group[0].name),
      tags: group.sort((a, b) => b.updateTime - a.updateTime),
    }));
    return result.sort((a, b) => b.tags[0].updateTime - a.tags[0].updateTime);
  });

  // 当前选中的tagName
  const currentTagName = ref<string | undefined>();
  // 当前选中的tagName的文件列表
  const currentTagFiles: Ref<FileItem[]> = ref([]);

  (async () => {
    tags.value = await loadTags();
    if (tags.value.length > 0) {
      currentTagName.value = tags.value[0].name;
    }
  })();

  watch(currentTagName, async (newTagName) => {
    if (newTagName) {
      console.log("currentTagName changed:", newTagName);
      currentTagFiles.value = await getFilesFromStorage(newTagName);
    }
  });

  // 监听文件列表变化，保存到本地存储
  watch(
    currentTagFiles,
    async (files: FileItem[]) => {
      if (currentTagName.value) {
        console.log("currentTagFiles changed:", files);
        await saveFilesToStorage(currentTagName.value, files);
      }
    },
    { deep: true }
  );

  async function loadTags(): Promise<Tag[]> {
    const tags: Tag[] = await store.get<Tag[]>("tags");
    if (!tags) {
      return [];
    }
    return tags.sort((a, b) => b.updateTime - a.updateTime);
  }

  function extractReqNumber(tagName: string): string {
    const match = tagName.match(/_((REQ)?[0-9]+)_(\d+)/);
    return match ? `${match[1]}-${match[3]}` : "其他";
  }

  // 从localStorage中获取指定tag的文件列表
  async function getFilesFromStorage(tagName: string): Promise<FileItem[]> {
    return await store.get<FileItem[]>(`tag-files:${tagName}`, []);
  }

  async function saveFilesToStorage(tagName: string, files: FileItem[]) {
    await store.set(`tag-files:${tagName}`, files);
  }

  async function updateTagUpdateTime() {
    const tag = tags.value.find((tag) => tag.name === currentTagName.value);
    if (tag) {
      tag.updateTime = new Date().getTime();
      tags.value = [...tags.value];
      await store.set("tags", tags.value);
    }
  }

  async function addTag(tag: string) {
    if (tags.value.some((item) => item.name === tag)) {
      return;
    }
    const newTag = {
      name: tag,
      updateTime: new Date().getTime(),
    };
    tags.value = [newTag, ...tags.value];
    currentTagName.value = tag;
    await store.set("tags", tags.value);
  }

  async function saveFileSelection() {
    await saveFilesToStorage(currentTagName.value!, currentTagFiles.value);
  }

  async function removeTag(tagName: string) {
    tags.value = tags.value.filter((tag) => tag.name !== tagName);
    tags.value = [...tags.value];
    if (currentTagName.value === tagName) {
      currentTagName.value = tags.value[0]?.name;
    }
    await store.delete(`tag-files:${tagName}`);
    await store.set("tags", tags.value);
  }

  async function addFile(filePath: string) {
    console.log("addFile", filePath);
    const tagName = currentTagName.value;
    if (!tagName) return null;
    if (currentTagFiles.value.some((file) => file.path === filePath)) {
      return null;
    }
    const fileName = await basename(filePath);
    const file: FileItem = {
      name: fileName,
      path: filePath,
      status: "加载中",
      rawStatus: "loading",
      workingVersion: "-",
      repositoryVersion: "-",
      selected: true,
    };
    currentTagFiles.value = [...currentTagFiles.value, file];
    await saveFilesToStorage(tagName, currentTagFiles.value);
    await updateCvsStatus(file);
    currentTagFiles.value = [...currentTagFiles.value];
    await saveFilesToStorage(tagName, currentTagFiles.value);
    await updateTagUpdateTime();
    return file;
  }

  async function addFiles(filePaths: string[]) {
    console.log("addFiles", filePaths);
    const tagName = currentTagName.value;
    if (!tagName) return null;
    const newFiles: FileItem[] = [];
    for (let filePath of filePaths) {
      if (currentTagFiles.value.some((file) => file.path === filePath)) {
        continue;
      }
      const fileName = await basename(filePath);
      const file: FileItem = {
        name: fileName,
        path: filePath,
        status: "加载中",
        rawStatus: "loading",
        workingVersion: "-",
        repositoryVersion: "-",
        selected: true,
      };
      newFiles.push(file);
    }
    if (newFiles.length === 0) {
      return;
    }
    currentTagFiles.value = [...currentTagFiles.value, ...newFiles];
    await saveFilesToStorage(tagName, currentTagFiles.value);
    await updateFileStatus(newFiles);
    currentTagFiles.value = [...currentTagFiles.value];
  }

  async function removeFile(filePath: string) {
    const tagName = currentTagName.value;
    if (!tagName) {
      return;
    }
    currentTagFiles.value = currentTagFiles.value.filter(
      (file) => file.path !== filePath
    );
    await saveFilesToStorage(tagName, currentTagFiles.value);
    await updateTagUpdateTime();
  }

  async function updateFileStatus(files: FileItem[]) {
    for (const file of files) {
      file.status = "加载中";
      file.rawStatus = "loading";
    }
    await Promise.all(
      files.map((file) =>
        replaceContent(
          file.path,
          /,建立时间:\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/,
          ""
        )
      )
    );
    const filePaths = files.map((file) => file.path);
    try {
      const statusResults = await cvsStatusMulti(filePaths);
      const statusMap = new Map(
        statusResults.map((status) => [status.filename, status])
      );
      files.forEach((file) => {
        const status = statusMap.get(file.name);
        if (status) {
          file.statusSnapshot = status;
          file.status = CVSStatusText[status.rawStatus];
          file.rawStatus = status.rawStatus;
          file.workingVersion = status.workingVersion;
          file.repositoryVersion = status.repositoryVersion;
          if (status.tags) {
            file.baseVersionTag = status.tags.find((tag => tag.name.includes('_PD_')))?.name;
          }
        } else {
          file.statusSnapshot = undefined;
          file.rawStatus = "Error";
          file.status = "ERROR";
        }
      });
    } catch (error) {
      console.log("批量更新状态失败:", error);
      files.forEach((file) => {
        file.statusSnapshot = undefined;
        file.rawStatus = "Error";
        file.status = "ERROR";
      });
    }
  }

  async function updateSelectedFilesStatus() {
    const selectedFiles = currentTagFiles.value.filter((file) => file.selected);
    await updateFileStatus(selectedFiles);
    currentTagFiles.value = [...currentTagFiles.value];
    await saveFilesToStorage(currentTagName.value!, currentTagFiles.value);
    await updateTagUpdateTime();
  }

  async function updateCvsStatus(file: FileItem) {
    const filePath = file.path;
    await replaceContent(
      filePath,
      /,\w{4,8}:\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/,
      ""
    );
    try {
      file.status = "加载中";
      file.rawStatus = "loading";
      const status = await cvsStatus(filePath);
      console.log(`cvs status ${filePath} result:`, status);
      file.statusSnapshot = status;
      file.status = CVSStatusText[status.rawStatus];
      file.rawStatus = status.rawStatus;
      file.workingVersion = status.workingVersion;
      file.repositoryVersion = status.repositoryVersion;
      file.baseVersionTag = status.tags.find((tag => tag.name.includes('_PD_')))?.name;
    } catch (error) {
      console.log("updateCvsStatus error", error);
      if (error instanceof NotCVSFileError) {
        file.statusSnapshot = undefined;
        file.rawStatus = "Not-CVS-File";
        file.status = "非CVS文件";
      } else {
        file.statusSnapshot = undefined;
        file.rawStatus = "Error";
        file.status = "ERROR";
      }
    }
    updateTagUpdateTime();
  }

  async function updateAllFilesStatus() {
    await updateFileStatus(currentTagFiles.value);
    currentTagFiles.value = [...currentTagFiles.value];
    await saveFilesToStorage(currentTagName.value!, currentTagFiles.value);
    await updateTagUpdateTime();
  }

  return {
    tags,
    tagGroups,
    currentTagName,
    currentTagFiles,
    addTag,
    removeTag,
    addFile,
    addFiles,
    removeFile,
    updateSelectedFilesStatus,
    updateAllFilesStatus,
    saveFileSelection,
    updateCvsStatus,
    updateTagUpdateTime,
  };
});
